package com.robaone.html;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.htmlcleaner.ContentToken;
import org.htmlcleaner.TagNode;

public class WidgetDescription {
	private Vector<WidgetDescription> children = new Vector<WidgetDescription>();
	private String widgetname = null;
	private Map attributes = new HashMap();
	private String m_content = null;
	private int m_itemindex;
	private String m_element;
	private HashMap m_tablecontent;

	public WidgetDescription(TagNode node) {
		this.m_element = node.getName();
		setWidgetname(this.getWidgetName(node));
		setAttributes(node.getAttributes());
		System.out.println(" Widget type = "+this.getWidgetname());
	}

	public WidgetDescription(ContentToken child) {
		setWidgetname("Text");
		setAttributes(null);
	}

	public WidgetDescription(String name) {
		setWidgetname(name);
		this.m_element = name;
		setAttributes(null);
	}

	private void setAttributes(Map attributes2) {
		this.attributes = attributes2;
	}

	public void addChildWidget(WidgetDescription widget){
		this.children.add(widget);
	}

	public String getWidgetname() {
		return widgetname;
	}

	private void setWidgetname(String widgetname) {
		this.widgetname = widgetname;
	}


	private Map getAttributes(){
		return this.attributes;
	}


	@SuppressWarnings("unchecked")
	private String getWidgetName(TagNode node) {
		if(node.getName().equals("div") || node.getName().equals("body") ||
				node.getName().equals("p")){
			if(node.getChildTagList().size() > 0){
				return "FlowPanel";
			}else{
				return "Label";
			}
		}else if(node.getName().equals("table")){
			return "FlexTable";
		}else if(node.getName().equals("tbody")){
			return "tbody";
		}else if(node.getName().equals("tr")){
			return "tr";
		}else if(node.getName().equals("td")){
			if(node.getChildTags().length > 0){
				return "FlowPanel";
			}else{
				return "InlineLabel";
			}
		}else if(node.getName().equals("form")){
			return "FormPanel";
		}else if(node.getName().equals("input") && node.getAttributeByName("type") != null){
			if(node.getAttributeByName("type").equals("button")){
				this.setContent(node.getAttributeByName("value"));
				return "Button";
			}else if(node.getAttributeByName("type").equals("text")){
				this.setContent(node.getAttributeByName("value"));
				return "TextBox";
			}else if(node.getAttributeByName("type").equals("password")){
				return "PasswordTextBox";
			}else if(node.getAttributeByName("type").equals("checkbox")){
				this.setContent(node.getAttributeByName("value"));
				return "CheckBox";
			}else if(node.getAttributeByName("type").equals("file")){
				return "FileUpload";
			}else if(node.getAttributeByName("type").equals("radio")){
				return "RadioButton";
			}
		}else if(node.getName().equals("select")){
			return "ListBox";
		}else if(node.getName().equals("button")){
			for(int i = 0; i < node.getChildren().size();i++){
				Object o = node.getChildren().get(i);
				System.out.println(o.getClass());
				if(o instanceof ContentToken){
					this.setContent(((ContentToken)o).getContent());
					break;
				}
			}
			return "Button";
		}else if(node.getName().equals("textarea")){
			return "TextArea";
		}else if(node.getName().equals("span")){
			if(node.getChildTags().length > 0){
				return "FlowPanel";
			}else{
				return "InlineLabel";
			}
		}else if(node.getName().equalsIgnoreCase("a")){
			return "Anchor";
		}else if(node.getName().equals("img")){
			return "Image";
		}
		this.setElement(node.getName());
		return "InlineHTML";
	}
	public String getAttributebyName(String name){
		try{
			return (String)this.getAttributes().get(name);
		}catch(NullPointerException e){
			return null;
		}
	}
	public String[] getAttributeNames(){
		try{
			return (String[])this.getAttributes().keySet().toArray(new String[0]);
		}catch(NullPointerException e){
			return new String[0];
		}
	}

	public void setContent(String content) {
		if(content != null && content.trim().length() > 0){
			this.m_content = content;
		}
	}

	private String getContent(){
		if(this.getWidgetname().equals("InlineHTML")){
			String content = "";
			content = "<"+this.m_element;
			for(int i = 0; i < this.getAttributeNames().length;i++){
				content += " ";
				content += this.getAttributeNames()[i] + "=\""+this.getAttributebyName(this.getAttributeNames()[i])+"\"";
			}
			content += ">";
			for(int i = 0; i < this.children.size();i++){
				WidgetDescription wd = this.children.get(i);
				if(wd.getWidgetname().equals("Text")){
					content += wd.getContent();
				}else if(wd.getWidgetname().equals("InlineHTML")){
					content += wd.getContent();
				}
			}
			content += "</"+this.m_element+">";
			return content;
		}else{
			return this.m_content;
		}
	}

	public String getInnerHTML(){
		String retval = "";
		for(int i = 0; i < this.children.size();i++){
			WidgetDescription wd = this.children.get(i);
			retval += "<"+wd.m_element;
			for(int j = 0; j < wd.getAttributeNames().length;j++){
				retval += " ";
				retval += wd.getAttributeNames()[j] + "=\""+wd.getAttributebyName(wd.getAttributeNames()[j])+"\"";
			}
			retval += ">";
			retval += wd.getInnerHTML();
			retval += "</"+wd.m_element+">";
		}
		return retval;
	}

	public String buildClass(String classname) {

		String str = "\nimport com.google.gwt.event.dom.client.ClickEvent;\n"+
		"import com.google.gwt.event.dom.client.ClickHandler;\n"+
		"import com.google.gwt.user.client.Window;\n"+
		"import com.google.gwt.user.client.ui.*;\n"+
		"\n"+
		this.getIncludes()+
		"public class "+classname+" extends Composite {\n";
		str += this.getWidgetDeclarations();
		str += this.getFieldDeclarations();
		str +=	"\tpublic "+classname+"(){\n";
		str += this.getWidgetInitializers();
		str += this.getWidgetProperties();
		str += this.getContentAssignment();
		str += this.getWidgetAssignments(null);
		str += "\t\tthis.initWidget("+this.getGwtVariableName()+");\n";
		str += this.getWidgetBinding();
		str += this.getWidgetHandlers();
		str += "\t}\n";
		str += this.getLoadMethod(null);
		str += this.getAccessorMethods();

		/*
		"_root.add(Main);\n"+
		"this.initWidget(_root);\n"+
		"}\n"+
		"public Label getMain(){\n"+
		"return this.Main;\n"+
		"}\n"+
		"}\n";*/

		str += "}";
		return str;
	}
	private String getLoadMethod(WidgetDescription parent) {
		String retval = "";
		String field = this.getAttributebyName(this.getNamespace()+":fields");
		if(this.m_element != null && (this.m_element.equals("body") ||
				this.getAttributebyName(this.getNamespace()+":body") != null)){
			retval += "\tpublic void load(";

			if(field != null){
				String[] fields = field.split("[;,]");
				for(int i = 0; i < fields.length;i++){
					if(i > 0)retval += ",";
					retval += fields[i]+"_local";
				}
			}
			retval += ") throws Exception {\n";
			if(field != null){
				String[] fields = field.split("[;,]");
				for(int i = 0; i < fields.length;i++){
					retval += "\t\tthis."+fields[i].split(" ")[1]+" = "+fields[i].split(" ")[1]+"_local;\n";
				}
			}
		}
		String get_str = this.getAttributebyName(this.getNamespace()+":bind_get");
		String widget = this.getWidgetname();
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		String gwt_name = this.getGwtVariableName();
		if(loop == null){
			if(get_str != null){
				get_str = this.convertHTMLtoJavaString(get_str);
				if(widget.equals("Label") || widget.equals("InlineLabel")){
					retval += "\t\t"+gwt_name+".setText("+get_str+");\n";
				}else if(widget.equals("FlowPanel")){
					for(int i = 0; i < this.children.size();i++){
						WidgetDescription wd = this.children.get(i);
						if(wd.getWidgetname().equals("Text")){
							retval += "\t\t"+gwt_name+".add(new InlineHTML("+get_str+"));\n";
						}else{
							retval += wd.getContentAssignment();
						}
					}
					return retval;
				}else if(widget.equals("InlineHTML")){
					retval += "\t\t"+gwt_name+".setHTML("+get_str+");\n";
				}else if(widget.equals("Button")){
					retval += "\t\t"+gwt_name+".setText("+get_str+");\n";
				}else if(widget.equals("TextBox")){
					retval +="\t\t"+gwt_name+".setText("+get_str+");\n";
				}else if(widget.equals("CheckBox")){
					retval += "\t\t"+gwt_name+".setValue("+get_str+");\n";
				}else if(widget.equals("RadioButton")){
					retval += "\t\t"+gwt_name+".setValue("+get_str+");\n";
				}else if(widget.equals("FlexTable")){
					retval += "";
					for(int i = 0;i < this.children.size();i++){
						retval += this.children.get(i).getContentAssignment();
					}
				}else if(widget.equals("Anchor")){
					return "\t\t"+gwt_name+".setHref("+get_str+");\n";
				}
			}
			for(int i = 0; i < this.children.size();i++){
				retval += this.children.get(i).getLoadMethod(this);
			}
		}else{
			/*
			 * Handle loop
			 */
			String str = "\t\t"+this.evaluateThis(loop)+"{\n";
			/*
			 * Handle loop children.
			 */
			str += this.getLoopContents(parent);
			str += "\t\t}\n";
			retval += str;
		}

		if(this.m_element != null && (this.m_element.equals("body") ||
				this.getAttributebyName(this.getNamespace()+":body") != null)){
			retval += "\t}\n";
		}
		return retval;
	}

	private String getLoopContents(WidgetDescription parent) {
		/*
		 * Widget declaration and initialization
		 */
		String retval  = "";
		if(!this.getWidgetname().equalsIgnoreCase("text")){
			String gwt_name = this.getGwtVariableName();
			if(this.getWidgetname().equals("RadioButton")){
				retval += "\t\t\t"+this.getWidgetname()+ " "+ gwt_name+ " = new "+this.getWidgetname()+"(\""+this.getAttributebyName("name")+"\");\n";
			}else{
				retval += "\t\t\t"+this.getWidgetname()+ " "+ gwt_name+ " = new "+this.getWidgetname()+"();\n";
			}
		}
		for(int i = 0; i < this.children.size();i++){
			retval += this.children.get(i).getLoopContents(this);
		}
		/*
		 * Get widget binding
		 */
		String get_str = this.getAttributebyName(this.getNamespace()+":bind_get");
		String widget = this.getWidgetname();
		if(get_str != null){
			get_str = get_str.replaceAll("'", "\"");
			if(widget.equals("Label") || widget.equals("InlineLabel")){
				retval += "\t\t\t"+this.getGwtVariableName()+".setText("+get_str+");\n";
			}else if(widget.equals("FlowPanel")){
				for(int i = 0; i < this.children.size();i++){
					WidgetDescription wd = this.children.get(i);
					if(wd.getWidgetname().equals("Text")){
						retval += "\t\t\t"+this.getGwtVariableName()+".add(new InlineHTML("+get_str+"));\n";
					}else{
						retval += wd.getContentAssignment();
					}
				}
				return retval;
			}else if(widget.equals("InlineHTML")){
				retval += "\t\t\t"+this.getGwtVariableName()+".setHTML("+get_str+");\n";
			}else if(widget.equals("Button")){
				retval += "\t\t\t"+this.getGwtVariableName()+".setText("+get_str+");\n";
			}else if(widget.equals("TextBox")){
				retval +="\t\t\t"+this.getGwtVariableName()+".setText("+get_str+");\n";
			}else if(widget.equals("CheckBox")){
				retval += "\t\t\t"+this.getGwtVariableName()+".setValue("+get_str+");\n";
			}else if(widget.equals("RadioButton")){
				retval += "\t\t\t"+this.getGwtVariableName()+".setValue("+get_str+");\n";
			}else if(widget.equals("FlexTable")){
				retval += "";
				for(int i = 0;i < this.children.size();i++){
					retval += this.children.get(i).getContentAssignment();
				}
			}else if(widget.equals("Anchor")){
				return "\t\t\t"+this.getGwtVariableName()+".setHref("+get_str+");\n";
			}
		}
		
		/*
		 * Get widget assignments
		 */
		if(this.getWidgetname().equals("FormPanel")){
			retval += "\t\t\tFlowPanel "+this.getGwtVariableName()+"_child = new FlowPanel();\n";
			retval += "\t\t\t"+this.getGwtVariableName()+".add("+this.getGwtVariableName()+"_child);\n";
		}
		for(int i = 0; i < this.children.size();i++){
			WidgetDescription child = this.children.get(i);
			retval += child.getWidgetAssignments(this);
		}
		if(parent != null){
			String gwt_name = parent.getGwtVariableName();
			String gwt_name_current = this.getAttributebyName(this.getNamespace()+":name");
			if(this.getItemindex() > 0){
				if(gwt_name_current == null){
					gwt_name_current = this.getGwtVariableName();
				}
				if(parent.getWidgetname().equals("FormPanel")){
					retval += "\t\t\t"+gwt_name+"_child.add("+gwt_name_current+");\n";
				}
				if(parent.getWidgetname().equals("FlowPanel")){
					retval += "\t\t\t"+gwt_name + ".add("+gwt_name_current+");\n";
				}else if(parent.getWidgetname().equals("InlineHTML")){
					//retval += gwt_name + ".add("+gwt_name_current+");\n";
				}else if(parent.getWidgetname().equals("Anchor")){
					//retval += gwt_name + ".setHTML("+gwt_name_current+".getElement().getInnerHTML());\n";
				}
				if(this.getWidgetname().equals("FlexTable")){
					retval += this.getLoopTableWidgetAssignments();
				}
			}
		}
		/*
		 * Get widget handlers
		 */
		//retval += this.getWidgetHandlers();
		return retval;
	}

	private String getFieldDeclarations() {
		String retval = "";
		if(this.m_element.equals("body") ||
				this.getAttributebyName(this.getNamespace()+":body") != null){
			String field = this.getAttributebyName(this.getNamespace()+":fields");
			if(field != null){
				String[] fields = field.split("[;,]");
				for(int i = 0; i < fields.length;i++){
					retval += "\tprivate "+fields[i]+";\n";
				}
			}
		}
		return retval;
	}

	private String getIncludes(){
		String retval = "";
		if(this.m_element.equals("body") ||
				this.getAttributebyName(this.getNamespace()+":body") != null){
			String include = this.getAttributebyName(this.getNamespace()+":include") == null ? this.getAttributebyName(this.getNamespace()+":import"): this.getAttributebyName(this.getNamespace()+":include");
			if(include != null){
				String[] includes = include.split("[;,]");
				for(int i = 0; i < includes.length;i++){
					retval += "import "+includes[i]+";\n";
				}
			}
		}
		return retval;
	}
	private String getWidgetHandlers() {
		String retval = "";
		/*
		 * Click Handlers
		 */
		String handler_str = this.getAttributebyName(this.getNamespace()+":clickhandler");
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(loop != null) return retval;
		if(handler_str != null){
			handler_str = this.convertHTMLtoJavaString(this.evaluateThis(handler_str));
			handler_str = handler_str.trim().endsWith(";") == true ? handler_str.trim() : handler_str.trim()+";";
			retval += "\t\t"+this.getGwtVariableName()+".addClickHandler(new ClickHandler(){\n"+
			"\t\t\t@Override\n"+
			"\t\t\tpublic void onClick(ClickEvent event){\n"+
			"\t\t\t\t"+handler_str+"\n"+
			"\t\t\t}\n"+
			"\t\t});\n";
		}
		/*
		 * Bind Put Handlers
		 */
		handler_str = this.getAttributebyName(this.getNamespace()+":bind_put");
		if(handler_str != null && (this.getWidgetname().equals("TextBox") || this.getWidgetname().equals("TextArea"))){
			handler_str = this.convertHTMLtoJavaString(this.evaluateThis(handler_str));
			handler_str = handler_str.trim().endsWith(";") == true ? handler_str.trim() : handler_str.trim()+";";
			retval += "\t\t"+this.getGwtVariableName()+".addValueChangeHandler(new ValueChangeHandler<String>("+
			"){\n"+
			"\n"+
			"\t\t\t@Override\n"+
			"\t\t\tpublic void onValueChange(ValueChangeEvent<String> event)"+
			" {\n"+
			"\t\t\t\t"+handler_str+"\n"+
			"\t\t\t}\n"+
			"\t\t\t\n"+
			"\t\t});\n";
		}else if(handler_str != null && this.getWidgetname().equals("RadioButton")){
			handler_str = this.convertHTMLtoJavaString(this.evaluateThis(handler_str));
			handler_str = handler_str.trim().endsWith(";") == true ? handler_str.trim() : handler_str.trim()+";";
			retval += "\t\t"+this.getGwtVariableName()+".addValueChangeHandler(new ValueChangeHandler<Boolean>("+
			"){\n"+
			"\n"+
			"\t\t\t@Override\n"+
			"\t\t\tpublic void onValueChange(ValueChangeEvent<Boolean> event)"+
			" {\n"+
			"\t\t\t\t"+handler_str+"\n"+
			"\t\t\t}\n"+
			"\t\t\t\n"+
			"\t\t});\n";
		}else if(handler_str != null && this.getWidgetname().equals("ListBox")){
			handler_str = this.convertHTMLtoJavaString(this.evaluateThis(handler_str));
			handler_str = handler_str.trim().endsWith(";") == true ? handler_str.trim() : handler_str.trim()+";";
			retval += "\t\t"+this.getGwtVariableName()+".addChangeHandler(new ChangeHandler("+
			"){\n"+
			"\n"+
			"\t\t\t@Override\n"+
			"\t\t\tpublic void onChange(ChangeEvent event)"+
			" {\n"+
			"\t\t\t\t"+handler_str+"\n"+
			"\t\t\t}\n"+
			"\t\t\t\n"+
			"\t\t});\n";
		}
		for(int i = 0; i < this.children.size();i++){
			retval += this.children.get(i).getWidgetHandlers();
		}
		return retval;
	}
	private String convertHTMLtoJavaString(String html){
		String retval = "";
		if(html != null){
			html = html.replaceAll("&quot;", "\"");
			html = html.replaceAll("&nbsp;", " ");
			html = html.replaceAll("&lt;","<");
			html = html.replaceAll("&gt;",">");
			return html;
		}
		return retval;
	}
	private String evaluateThis(String handlerStr) {
		String retval = "";
		if(handlerStr == null) return null;
		Pattern pattern = Pattern.compile("[(\\s=]this[);\\s]");
		handlerStr = " "+handlerStr+" ";
		Matcher matcher = pattern.matcher(handlerStr);
		int end = -1;
		int start = 0;
		while(matcher.find()){
			retval += handlerStr.substring(start,matcher.start()+1);
			start = matcher.start();
			end = matcher.end();
			if(this.getWidgetname().equals("Label") || this.getWidgetname().equals("InlineLabel") ||
					this.getWidgetname().equals("TextBox") || this.getWidgetname().equals("TextArea")){
				retval += this.getGwtVariableName()+".getText()";
			}else if(this.getWidgetname().equals("RadioButton")){
				retval += this.getGwtVariableName()+".getValue()";
			}else if(this.getWidgetname().equals("ListBox")){
				retval += this.getGwtVariableName()+".getValue("+this.getGwtVariableName()+".getSelectedIndex())";
			}
			start = end-1;
		}
		retval += handlerStr.substring(start);
		return retval.trim();
	}

	private String getWidgetBinding() {
		String set_str = this.getAttributebyName(this.getNamespace()+":bind_set");
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(loop != null) return "";
		String retval = "";
		if(set_str != null){
			System.out.println("set "+set_str);
		}
		for(int i = 0;i < this.children.size();i++){
			retval += this.children.get(i).getWidgetBinding();
		}
		return retval;
	}

	private String getWidgetProperties() {
		String[] names = this.getAttributeNames();
		String retval = "";
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(loop != null) return retval;
		for(int i = 0; i < names.length;i++){
			if(names[i].startsWith(this.getNamespace()+":")){
				continue;
			}else if(names[i].equals("class")){
				if(!this.getWidgetname().equals("InlineHTML")){
					retval += "\t\t"+this.getGwtVariableName()+".setStyleName(\""+this.getAttributebyName(names[i])+"\");\n";
				}
				if(this.getWidgetname().equals("FlexTable")){
					retval += this.getTableAttributes();
				}
			}else{
				if(!this.getWidgetname().equals("InlineHTML")){
					if(this.getWidgetname().equals("Button")){
						if(!names[i].equals("type") && !names[i].equals("value")){
							retval += "\t\t"+this.getGwtVariableName()+".getElement().setAttribute(\""+names[i]+"\",\""+this.getAttributebyName(names[i])+"\");\n";
						}
					}else if(this.getWidgetname().equals("TextBox")){
						if(!names[i].equals("type") && !names[i].equals("value")){
							retval += "\t\t"+this.getGwtVariableName()+".getElement().setAttribute(\""+names[i]+"\",\""+this.getAttributebyName(names[i])+"\");\n";
						}
					}else if(this.getWidgetname().equals("CheckBox")){
						if(!names[i].equals("type") && !names[i].equals("value")){
							retval += "\t\t"+this.getGwtVariableName()+".getElement().setAttribute(\""+names[i]+"\",\""+this.getAttributebyName(names[i])+"\");\n";
						}
					}else if(this.getWidgetname().equals("tr")){
						retval += "\t\t//TODO: Set the rowFormatter to "+names[i]+" = "+this.getAttributebyName(names[i])+"\n";
					}else if(this.getWidgetname().equals("td")){
						retval += "\t\t//TODO: Set the cellFormatter to "+names[i]+" = "+this.getAttributebyName(names[i])+"\n";
					}else if(this.getWidgetname().equals("Anchor")){
						retval += "\t\t"+this.getGwtVariableName()+".setHref(\""+this.getAttributebyName(names[i])+"\");\n";
					}else{
						retval += "\t\t"+this.getGwtVariableName()+".getElement().setAttribute(\""+names[i]+"\",\""+this.getAttributebyName(names[i])+"\");\n";
					}
				}
			}
		}
		for(int i = 0; i < this.children.size();i++){
			retval += this.children.get(i).getWidgetProperties();
		}
		return retval;
	}

	private String getTableAttributes() {
		String retval = "";
		String[] keys = (String[])this.m_tablecontent.keySet().toArray(new String[0]);
		for(int i = 0; i < keys.length;i++){
			//rowstyle.
			if(keys[i].startsWith("rowstyle.")){
				String style = (String)this.m_tablecontent.get(keys[i]);
				if(style != null){
					String[] tokens = keys[i].split("[\\.]");
					int row = Integer.parseInt(tokens[1]);
					retval += "\t\t"+this.getGwtVariableName()+".getRowFormatter().setStyleName("+row+", \""+style+"\");\n";
				}
			}
			//cellstyle.
			if(keys[i].startsWith("cellstyle.")){
				String style = (String)this.m_tablecontent.get(keys[i]);
				if(style != null){
					String[] tokens = keys[i].split("[\\.]");
					int row = Integer.parseInt(tokens[1]);
					int column = Integer.parseInt(tokens[2]);
					retval += "\t\t"+this.getGwtVariableName()+".getFlexCellFormatter().setStyleName("+row+", "+column+", \"style\");\n";
				}
			}
			//cellwidth.
			if(keys[i].startsWith("cellwidth.0.")){
				String width = (String)this.m_tablecontent.get(keys[i]);
				if(width != null){
					String[] tokens = keys[i].split("[\\.]");
					int row = Integer.parseInt(tokens[1]);
					int column = Integer.parseInt(tokens[2]);
					retval += "\t\t"+this.getGwtVariableName()+".getColumnFormatter().setWidth("+column+", \""+width+"\");\n";
				}
			}
		}
		return retval;
	}

	private String getWidgetAssignments(WidgetDescription parent) {
		String retval = "";
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(loop != null) return retval;
		if(this.getWidgetname().equals("FormPanel")){
			retval += "\t\tFlowPanel "+this.getGwtVariableName()+"_child = new FlowPanel();\n";
			retval += "\t\t"+this.getGwtVariableName()+".add("+this.getGwtVariableName()+"_child);\n";
		}
		for(int i = 0; i < this.children.size();i++){
			WidgetDescription widget = this.children.get(i);
			retval += widget.getWidgetAssignments(this);
		}
		if(parent != null){
			String gwt_name = parent.getGwtVariableName();
			String gwt_name_current = this.getAttributebyName(this.getNamespace()+":name");
			if(this.getItemindex() > 0){
				if(gwt_name_current == null){
					gwt_name_current = this.getGwtVariableName();
				}
				if(parent.getWidgetname().equals("FormPanel")){
					retval += "\t\t"+gwt_name+"_child.add("+gwt_name_current+");\n";
				}
				if(parent.getWidgetname().equals("FlowPanel")){
					retval += "\t\t"+gwt_name + ".add("+gwt_name_current+");\n";
				}else if(parent.getWidgetname().equals("InlineHTML")){
					//retval += gwt_name + ".add("+gwt_name_current+");\n";
				}else if(parent.getWidgetname().equals("Anchor")){
					//retval += gwt_name + ".setHTML("+gwt_name_current+".getElement().getInnerHTML());\n";
				}
				if(this.getWidgetname().equals("FlexTable")){
					retval += this.getTableWidgetAssignments();
				}
			}
		}
		return retval;
	}

	private String getContentAssignment() {
		String widget = this.getWidgetname();
		String gwt_name = this.getGwtVariableName();
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(loop != null) return "";
		if(widget.equals("Label") || widget.equals("InlineLabel")){
			String content = "";
			for(int i = 0; i < this.children.size();i++){
				if(i > 0){
					content += " ";
				}
				if(this.children.get(i).getContent() != null){
					content += this.children.get(i).getContent();
				}
			}
			return "\t\t"+gwt_name+".setText(\""+this.convert(content)+"\");\n";
		}else if(widget.equals("FormPanel")){
			String retval = "";
			for(int i = 0; i < this.children.size();i++){
				WidgetDescription wd = this.children.get(i);
				if(wd.getWidgetname().equals("Text")){
					retval += "\t\t"+gwt_name+".add(new InlineHTML(\""+this.convert(wd.getContent())+"\"));\n";
				}else{
					retval += wd.getContentAssignment();
				}
			}
			return retval;
		}else if(widget.equals("FlowPanel")){
			String retval = "";
			for(int i = 0; i < this.children.size();i++){
				WidgetDescription wd = this.children.get(i);
				if(wd.getWidgetname().equals("Text")){
					retval += "\t\t"+gwt_name+".add(new InlineHTML(\""+this.convert(wd.getContent())+"\"));\n";
				}else{
					retval += wd.getContentAssignment();
				}
			}
			return retval;
		}else if(widget.equals("InlineHTML")){
			return "\t\t"+gwt_name+".setHTML(\""+this.convert(this.getContent())+"\");\n";
		}else if(widget.equals("Button")){
			if(this.getAttributebyName("value") != null){
				return "\t\t"+gwt_name+".setText(\""+this.convert(this.getAttributebyName("value"))+"\");\n";
			}else{
				return "\t\t"+gwt_name+".setText(\""+this.convert(this.getContent())+"\");\n";
			}
		}else if(widget.equals("TextBox")){
			return "\t\t"+gwt_name+".setText(\""+this.convert(this.getContent())+"\");\n";
		}else if(widget.equals("CheckBox")){
			return "\t\t//TODO: Checkbox value for "+gwt_name+" content = \""+this.convert(this.getContent())+"\"\n";
		}else if(widget.equals("FlexTable")){
			String retval = "";
			for(int i = 0;i < this.children.size();i++){
				retval += this.children.get(i).getContentAssignment();
			}
			return retval;
		}else if(widget.equals("Anchor")){
			return "\t\t"+gwt_name+".setHTML(\""+this.convert(this.getInnerHTML())+"\");\n";
		}
		return "";
	}
	private String getLoopTableWidgetAssignments() {
		return this.getTableWidgetAssignments(true);
	}
	private String getTableWidgetAssignments(boolean loop){
		String retval = "";
		//Find Assignments
		boolean morerows = true;
		boolean morecolumns = true;
		for(int row = 0;morerows;row++){
			morecolumns = true;
			for(int column = 0;morecolumns ;column++){
				WidgetDescription cellcontent = (WidgetDescription)this.m_tablecontent.get("widget."+row+"."+column);
				if(column == 0 && cellcontent == null){
					morerows = false;
				}
				if(cellcontent == null){
					morecolumns = false;
				}else{
					//Handle column data
					if(loop) retval += "\t";
					retval += "\t\t"+this.getGwtVariableName()+".setWidget("+row+","+column+","+cellcontent.getGwtVariableName()+");\n";
				}
			}
		}
		return retval;
	}
	private String getTableWidgetAssignments() {
		return this.getTableWidgetAssignments(false);
	}

	private String convert(String line) {
		if(line == null) return "";
		line = line.replaceAll("&nbsp;", " ");
		String retval = "";
		for(int i = 0; i < line.length();i++){
			retval += this.encode(line.charAt(i));
		}

		return retval;
	}
	private String encode(char charAt) {
		switch( charAt){
		case '\n':
			return "\\n";
		case '\r':
			return "\\r";
		case '\t':
			return "\\t";
		case '"':
			return "\\\"";
		case '\\':
			return "\\\\";
		default:
			return charAt+"";
		}
	}
	private String getGwtVariableName() {
		String gwt_name = this.getAttributebyName(this.getNamespace()+":name");
		if(gwt_name == null){
			String prefix = this.removeVowels(this.getWidgetname().toLowerCase());
			gwt_name = prefix+this.getItemindex();
		}
		return gwt_name;
	}
	private String removeVowels(String str){
		String retval = "";
		if(str == null) return null;
		for(int i = 0; i < str.length();i++){
			char c = str.charAt(i);
			if(c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' ||
					c == 'o' || c == 'O' || c == 'u' || c == 'U'){
				retval += "";
			}else{
				retval += str.charAt(i);
			}
		}
		return retval;
	}
	private String getAccessorMethods() {
		String retval = "";
		String gwt_name = this.getAttributebyName(this.getNamespace()+":name");
		if(gwt_name != null){
			retval += "\tpublic "+this.getWidgetname()+" get"+gwt_name.toUpperCase().charAt(0)+gwt_name.toLowerCase().substring(1)+"(){\n";
			retval += "\t\treturn this."+gwt_name+";\n";
			retval += "\t}\n";
		}
		for(int i = 0; i < this.children.size();i++){
			WidgetDescription widget = this.children.get(i);
			retval += widget.getAccessorMethods();
		}
		return retval;
	}

	private String getNamespace() {
		return WidgetGenerator2.getNamespace();
	}

	private String getWidgetInitializers() {
		String retval = "";
		String attribute_names[] = this.getAttributeNames();
		boolean labeled = false;
		for(int i = 0; i < attribute_names.length;i++){
			if(attribute_names[i].startsWith(this.getNamespace()+":")){
				labeled = true;
				break;
			}
		}
		String gwt_name = this.getAttributebyName(this.getNamespace()+":name");
		if(labeled == false){
			if(!this.getWidgetname().equalsIgnoreCase("text")){
				gwt_name = this.getGwtVariableName();
				if(this.getWidgetname().equals("RadioButton")){
					retval += "\t\t"+this.getWidgetname()+ " "+ gwt_name+ " = new "+this.getWidgetname()+"(\""+this.getAttributebyName("name")+"\");\n";
				}else{
					retval += "\t\t"+this.getWidgetname()+ " "+ gwt_name+ " = new "+this.getWidgetname()+"();\n";
				}
			}
		}
		for(int i = 0; i < this.children.size();i++){
			WidgetDescription widget = this.children.get(i);
			retval += widget.getWidgetInitializers();
		}

		return retval;
	}

	protected void setItemindex(int itemindex) {
		this.m_itemindex = itemindex;
	}
	protected int getItemindex(){
		return this.m_itemindex;
	}

	private String getWidgetDeclarations() {
		String str = "";
		String attribute_names[] = this.getAttributeNames();
		boolean labeled = false;
		for(int i = 0; i < attribute_names.length;i++){
			if(attribute_names[i].startsWith(this.getNamespace()+":")){
				labeled = true;
				break;
			}
		}
		String gwt_name = this.getGwtVariableName();
		String loop = this.getAttributebyName(this.getNamespace()+":loop");
		if(labeled && loop == null){
			if(this.getWidgetname().equals("Text")){
				//return str;
			}else{
				if(this.getWidgetname().equals("RadioButton")){
					str += "\tprivate "+this.getWidgetname()+" "+gwt_name+" = new "+this.getWidgetname()+"(\""+this.getAttributebyName("name")+"\");\n";
				}else{
					str += "\tprivate "+this.getWidgetname()+" "+gwt_name+" = new "+this.getWidgetname()+"();\n";
				}
			}
		}
		if(loop == null){
			for(int i = 0; i < this.children.size();i++){
				WidgetDescription child = this.children.get(i);
				str += child.getWidgetDeclarations();
			}
		}
		return str;
	}

	private String getElement() {
		return this.m_element;
	}
	private void setElement(String element){
		this.m_element = element;
	}

	public void setContent(HashMap statevariables) {
		this.m_tablecontent = statevariables;
	}
}
